package com.amkai.aes.webservice.binary.objecthandler.registration;

import java.io.Serializable;
import java.util.List;

import com.amkai.aes.aescommon.manager.DepartmentManager;
import com.amkai.aes.aescommon.service.binary.job.AppointmentsToRegistrationJob;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.generatedbeans.organization.DepartmentKind;
import com.amkai.aes.generatedbeans.reference.PersonReference;
import com.amkai.aes.generatedbeans.scheduling.AbstractAppointment;
import com.amkai.aes.generatedbeans.scheduling.AppointmentStatusInfo;
import com.amkai.aes.generatedbeans.scheduling.ResourceConnection;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

public class AppoitmentsToRegistrationHandler implements JobObjectHandler<AppointmentsToRegistrationJob, Serializable, AbstractAppointment[]> {

	@Override
	public AbstractAppointment[] process(AppointmentsToRegistrationJob job, Serializable object) throws Exception {
		SessionManager sm = SiteManager.Start();
		sm.openSession();
		
		Department dep = sm.get(Department.class, job.getModuleDepartment().getId());
		
		String className = "AbstractAppointment";
		
		//AES-9221
		if (DepartmentManager.isPMLike(dep)) {
			className = "PracticeManagementAppointment";
		}
		else if (DepartmentManager.isSCLike(dep)) {
			className = "SurgeryCenterAppointment";
		}

		List appointments = sm.execute("FROM "+ className +" aa " +
							  "left join fetch aa.resourceConnections as rescon "+
							  "left join fetch rescon.reservation as res "+
							  "left join fetch res.schedulingResource as sr "+
							  "left join fetch sr.reference as ref " +
							  "where exists(FROM PersonReference persref WHERE persref.id = ref.id AND persref.person = :persid) AND " +
							  "		aa.department = :depid AND " +
							  "		exists (FROM AppointmentStatusInfo asi WHERE asi.abstractScheduleIssue.id = aa.id " +
							  "			AND asi.changeDate = (SELECT max(changeDate) FROM AppointmentStatusInfo aai WHERE aai.abstractScheduleIssue.id = aa.id)) " +
//							  "			AND asi.statusKindWrapper NOT IN ("+ AppointmentStatusKind.CANCELED.ordinal() +", "+ AppointmentStatusKind.NO_SHOW.ordinal() +")) " +
							  " ORDER BY aa.beginTime")
							  .setLong("persid", job.getPersonId()).setLong("depid", job.getModuleDepartment().getId()).list();
		
		for(Object o: appointments) {
			
			AbstractAppointment aa = (AbstractAppointment)o;
			
			aa.getAppointmentType().getName();
			
			for(AppointmentStatusInfo asi : aa.getAppointmentStatusInfoes()) {
				asi.getChangeDate();
			}
			
			for(ResourceConnection resc : aa.getResourceConnections()) {
				if (resc.getReservation() != null) { 
					resc.getReservation().getBeginTime();
					if (resc.getReservation().getSchedulingResource() != null && 
						resc.getReservation().getSchedulingResource().getReference() != null && 
						resc.getReservation().getSchedulingResource().getReference() instanceof PersonReference) {
						
						((PersonReference)resc.getReservation().getSchedulingResource().getReference()).getPerson().getLastName();
					}
				}
			}
		}
		
		sm.closeSession();
		
		AbstractAppointment[] res = new AbstractAppointment[appointments.size()];
		int i=0;
		for(Object o : appointments) {
			
			if (o != null) {
				AbstractAppointment aa = (AbstractAppointment)o;
				res[i] = aa;
				i++;
			}
		}
		
		return res;
	}

}
